package org.wheel.plugins.toolkit.sql.page;

import cn.hutool.core.util.StrUtil;

public enum BuiltinPaginationStrategy implements PaginationStrategy {

    MYSQL((sql, pageNo, pageSize) -> StrUtil.format("{} LIMIT {} offset {}", sql, pageSize, (pageNo-1)*pageSize)),
    ORACLE_OLD((sql, pageNo, pageSize) -> StrUtil.format(
            "SELECT * FROM (SELECT t.*, ROWNUM rn FROM ({}) t WHERE ROWNUM <= {}) WHERE rn > {}",
            sql, pageNo*pageSize, (pageNo-1)*pageSize)),
    ORACLE((sql, pageNo, pageSize) -> StrUtil.format(
            "{} OFFSET {} ROWS FETCH NEXT {} ROWS ONLY", sql, (pageNo - 1) * pageSize, pageSize)),
    DB2((sql, pageNo, pageSize) -> StrUtil.format("{} OFFSET {} ROWS FETCH FIRST {} ROWS ONLY", sql, (pageNo - 1) * pageSize, pageSize)),
    POSTGRESQL((sql, pageNo, pageSize) -> StrUtil.format("{} OFFSET {} LIMIT {}", sql, (pageNo - 1) * pageSize, pageSize)),
    SQL_SERVER((sql, pageNo, pageSize) -> StrUtil.format(
            "SELECT TOP {} * FROM ({}) t WHERE t.__row > {} ORDER BY t.__row",
            pageSize, sql, (pageNo - 1) * pageSize));

    private final PaginationStrategy delegate;
    BuiltinPaginationStrategy(PaginationStrategy delegate) { this.delegate = delegate; }

    @Override
    public String generatePaginationQuery(String sql, long pageNo, long pageSize) {
        return delegate.generatePaginationQuery(sql, pageNo, pageSize);
    }
}